package rgr;

import process.Actor;
import process.IWaitCondition;
import queues.QueueForTransactions;
import rnd.Randomable;

//Клас для абстракції Самоскид
public class Lorry extends Actor {

	// Тривалість роботи самосвалу
	private double finishTime;

	// Черга самосвалів у дорозі
	private QueueForTransactions queueLorryOnRoad;

	// Черга самосвалів до нантажувача
	private QueueForTransactions queueToEcsc;

	// Генератор часу, що витрачається на дорогу в один кінець
	private Randomable rnd;

	// Місткіть кузову
	private double bodySize;

	// Рівень завантаження кузову
	private double body;

	public Lorry(String name, GUI gui, Model model){
		this.setNameForProtocol(name);
		this.queueToEcsc = model.getQueueToEcsc();
		this.queueLorryOnRoad = model.getQueueLorryOnRoad();
		this.finishTime = gui.getChooseDataFinishTime().getDouble();
		this.bodySize = gui.getChooseDataBodySize().getDouble();
		this.rnd = gui.getRndLorry();
	}

	// Правила дії самосвалу
	public void rule() {
		// Умова заповнення кузову
		// Створюється один раз, до основного циклу роботи
		IWaitCondition bodyIsFull = new IWaitCondition() {
			public boolean testCondition() {
				return isFull();
			}
			public String toString() {
				return ("кузов має бути повним");
			}
		};
		// Цикл правил дії самосвалу
		while (getDispatcher().getCurrentTime() <= finishTime) {
			// Самосвал їде до екскалатора
			// i реєструється у списку самоскидів, що їдуть
			queueLorryOnRoad.addLast(this);
			holdForTime(rnd.next());
			// вилучає себе із відповідного списку
			queueLorryOnRoad.remove(this);
			// Самосвал стає у чергу до екскалатора,
			queueToEcsc.addLast(this);
			//Чекає поки завантажать
			try {
				waitForCondition(bodyIsFull);
			} catch (Exception e) {
				return;
			}
			// Самосвал вилучає себе із черги
			queueToEcsc.remove(this);

			// Самосвал їде на розвантаження
			// реєструється у списку самоскидів, що їдуть
			queueLorryOnRoad.add(this);
			holdForTime(rnd.next());
			// вилучає себе із списку самоскидів, що їдуть
			queueLorryOnRoad.remove(this);
			getDispatcher().printToProtocol(getNameForProtocol()+" розвантажується");
			// Самоскид розвантажується
			body = 0;
		}
	}

	// /////////////////////////////////////
	// Методи, які використовує навантажувач
	// /////////////////////////////////////
	// Метод добавления камней в кузов самосвала
	public void addPortion() {
		body++;
		getDispatcher().printToProtocol(
				getNameForProtocol()+"- у кузові стало " + body);
	}

	// Проверка, заполнен ли кузов
	public boolean isFull() {
		return body >= bodySize;
	}

}
